﻿using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
using System.Xml.Serialization;
using Newtonsoft.Json;

namespace GuoZhiQi.MiddleCache.Common.Serialization
{
    public static class SerializationHelper
    {
        #region Generic Serializer.

        public static void SerializeObject<T>(IFormatter formatter, Stream stream, T objectToSerialize)
        {
            stream.Position = 0;
            formatter.Serialize(stream, objectToSerialize);
        }

        public static T DeserializeObject<T>(IFormatter formatter, Stream stream)
        {
            stream.Position = 0;
            return (T)formatter.Deserialize(stream);
        }

        #endregion Generic Serializer.

        #region Binary serializer.

        public static void BinarySerializeObject<T>(Stream stream, T objectToSerialize)
        {
            IFormatter formatter = new BinaryFormatter();
            SerializationHelper.SerializeObject<T>(formatter, stream, objectToSerialize);
        }

        public static T BinaryDeserializeObject<T>(Stream stream)
        {
            IFormatter formatter = new BinaryFormatter();
            return SerializationHelper.DeserializeObject<T>(formatter, stream);
        }

        #endregion Binary serializer.

    

        public static void SoapSerializeObject<T>(Stream stream, T objectToSerialize)
        {
            IFormatter formatter = new SoapFormatter();
            SerializationHelper.SerializeObject<T>(formatter, stream, objectToSerialize);
        }

        public static T SoapDeserializeObject<T>(Stream stream)
        {
            IFormatter formatter = new SoapFormatter();
            return SerializationHelper.DeserializeObject<T>(formatter, stream);
        }

      

        public static void XmlSerializeObject<T>(Stream stream, T objectToSerialize)
        {
            stream.Position = 0;
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            serializer.Serialize(stream, objectToSerialize);
        }

        public static T XmlDeserializeObject<T>(Stream stream)
        {
            stream.Position = 0;
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            return (T)serializer.Deserialize(stream);
        }

     
        public static void JsonSerializeObject<T>(Stream stream, T objectToSerialize)
           where T : new()
        {
            string jsonData = JsonConvert.SerializeObject(objectToSerialize);
            byte[] data = Encoding.UTF8.GetBytes(jsonData);

            for (int i = 0; i < data.Length; i++)
            {
                stream.WriteByte(data[i]);
            }
        }

        public static T JsonDeserializeObject<T>(Stream stream)
           where T : new()
        {
            byte[] data = StreamUtil.ReadToEnd(stream);

            string jsonData = Encoding.UTF8.GetString(data);
            T obj = new T();
            JsonConvert.PopulateObject(jsonData, obj);
            return obj;
        }
    }
}
